<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace buwang\base;

use app\common\model\MemberMiniapp;
use app\manage\model\Config as ConfigModel;
use buwang\exception\MiniappException;
use buwang\service\AuthService;
use think\facade\View;
use buwang\service\MiniappService;
use think\Response;

class MemberBaseController extends Manage
{
    //用户应用信息
    protected $member_miniapp;
    //用户应用id
    protected $member_miniapp_id;
    //应用id
    protected $miniapp_id;
    //应用信息
    protected $miniapp;


    // 初始化
    protected function initialize()
    {
        parent::initialize();
        $this->scopes = 'member';
        $this->miniapp_id = 0;
        //租户购买的应用id
        $member_app_id = request()->param('miniapp_id/d') ?: 0;
        //判断如果路由附加了参数bwsaas为true，就意味着必须传miniapp_id来标识租户操作哪个应用
        $bwsaas = $this->request->param('bwsaas/b');
        //页面未传递租户应用ID时，根据访问的应用目录获取租户应用ID
        $dir = app('http')->getName();
        if (!$member_app_id && !in_array($dir,['manage','install','api']) && $this->uid) {
            $member_app_id = MemberMiniapp::where('member_id', $this->uid)->where('miniapp_id', function ($query) use ($dir) {
                $query->name('miniapp')->where('dir', $dir)->where('status', '1')->field('id');
            })->value('id') ?: 0;
        }

        if ($member_app_id || $bwsaas) {
            if (!$this->uid) throw new MiniappException('此操作必须进行登录，登录信息验证失败', 401);
            //获取租户所属应用信息
            $this->member_miniapp = MemberMiniapp::where('member_id', $this->uid)->where('id', $member_app_id)->find();
            //是否已购买
            if (!$this->member_miniapp) throw new MiniappException('未找到所属应用,请先开通应用');

            $this->member_miniapp_id = $this->member_miniapp['id'];
            //TODO 购买的应用是否已过期

            $this->miniapp = $this->member_miniapp->miniapp;
            $this->miniapp_id = $this->miniapp['id'] ?: 0;
            View::assign('miniapp', $this->miniapp);
            View::assign('member_miniapp', $this->member_miniapp);
            View::assign('member_miniapp_id', $this->member_miniapp_id);
        }
    }

    protected function isMemberAppAuth($code = 401)
    {
        if (!$this->miniapp) throw new MiniappException('获取系统应用信息失败',$code);
        if (!$this->member_miniapp) throw new MiniappException('获取所属应用信息失败',$code);
        MiniappService::checkMiniappExpire($this->member_miniapp); //校验应用是否过期

    }

    /**
     * 当前租户是否有应用操作权限
     * @param $member_miniapp_id
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    protected function isValidMember($member_miniapp_id)
    {
        //获取租户应用信息
        $member_miniapp = MemberMiniapp::find($member_miniapp_id);
        if(!$member_miniapp) {
            throw new MiniappException('未找到应用');
        }
        if($member_miniapp['member_id'] !== $this->user->top_id) {
            throw new MiniappException('无应用操作权限');
        }
    }

    /**
     * 获取当前用户的权限内菜单树.
     *
     * @return \think\Response
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUserAppAuthedMenuTree():Response {
        if (!$this->isUserLogin) {
            return $this->error('need login');
        }
        $param = $this->request->param();
        $this->validate($param, [
            'app_name' => 'require|length:2,30|regex:/^[a-zA-Z\-_]+$/',
        ]);

        if (in_array($param['app_name'], [
            'admin',
            'api',
            'home',
        ])) {
            return $this->error('invalid request: illegal app name');
        }

        // 默认取当前用户.
        $uid = $this->user->sub_member_id;
        // 如果是顶级租户账号.
        if ($uid == 0) {
            $uid = $this->user->top_id;
        }

        return $this->success(
            'ok',
            AuthService::getAppAuthTree(
                $uid,// 用户当前登录ID. 不是顶级ID.
                'member',
                $param['app_name']
            )
        );
    }

    /**
     * 获取租户配置.
     *
     * @param mixed $tab_name
     * @param mixed $type
     * @param mixed $config_ids
     * @param mixed $app
     * @param mixed $plugin
     *
     * @return \think\Response|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function showMemberConfig(
        $tab_name = NULL,
        $type = NULL,
        $config_ids = NULL,
        $app = NULL,
        $plugin = NULL
    ) {
        $tab_name   = $tab_name ? : ($this->request->get('tab_name') ? : NULL);//配置分类
        $type       = $type ? : ($this->request->get('type') ? : NULL);//配置类型
        $config_ids = $config_ids ? : ($this->request->get('config_ids') ? : NULL);//配置id
        $app        = $app ? : ($this->request->get('app') ? : NULL);//app标识
        $plugin     = $plugin ? : ($this->request->get('plugin') ? : NULL);//插件标识

        // 20230621 判断是不是租户后台请求
        $member_id = 0;
        if ($this->scopes == "member") {
            $member_id = $this->uid;//获取中间件自动挂取的租户用户ID
        }
        // 获取租户应用目录
        if (!$app) {
            $app_temp = app('http')->getName();
            $app      = !in_array($app_temp, ['manage', 'install', 'api', 'home']) ? $app_temp : $app;
        }
        $data = ConfigModel::getShowData($tab_name, $type, $member_id, 'member', $config_ids, $app);

        // 如果传了插件标识，则优先取插件下的配置模板
        if ($plugin) {
            $configFile = ADDON_PATH . $plugin . DS . 'view' . DS . 'config' . DS . 'config.html';
            $viewFile   = is_file($configFile) ? $configFile : '';
            // 如果传了应用标识，则优先取应用下的配置模板
        } elseif ($app) {
            $configFile = app()->getRootPath() . DS . 'app' . DS . $app . DS . 'view' . DS . 'config' . DS . 'config.html';
            $viewFile   = is_file($configFile) ? $configFile : '';
        } else {
            $viewFile = '';
        }
        if ($this->request->isAjax()) {
            return $this->success('success', ['show' => $data, 'app' => $app]);
        }

        return view($viewFile, ['show' => $data, 'app' => $app]);
    }

    /**
     * 写入租户配置.
     *
     * @return \think\Response|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function setMemberValues() {
        if ($this->request->isPost()) {
            $param = $this->request->param();
            $res   = ConfigModel::setValues($param, 0, 'member', true);
            if (!$res) {
                return $this->error(ConfigModel::getError('设置失败'));
            }

            return $this->success('更新成功');
        }

    }

    /**
     * 写入租户配置.
     *
     * @return \think\Response|void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function setMemberValuesNew() {
        if ($this->request->isPost()) {
            $param = $this->request->param();
            // 20230621 判断是不是租户后台请求
            $member_id = 0;
            if ($this->scopes == "member") {
                $member_id = $this->uid;// 获取中间件自动挂取的租户用户ID
            }
            // 获取租户应用目录
            $app = $param['app'] ?? "";
            if (!$app) {
                $app_temp = app('http')->getName();
                $app      = !in_array($app_temp, ['manage', 'install', 'api', 'home']) ? $app_temp : $app;
            }

            $res = ConfigModel::setValuesNew($param, $member_id, 'member', $app, true);
            if (!$res) {
                return $this->error(ConfigModel::getError('设置失败'));
            }

            return $this->success('更新成功');
        }

    }
}